package com.lqk.demo.designpatterns.balkingmode;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @author lqk
 * @date 2021/12/26 16:20
 *
 * 两阶段终止，保证改线程只能调用一次
 * 即犹豫模式：Balking
 */
@Slf4j
public class TestBalking1 {
    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination3 tpt = new TwoPhaseTermination3();
        tpt.start();
        TimeUnit.MILLISECONDS.sleep(3500);
        tpt.stop();
        tpt.stop();
        tpt.stop();
    }
}

@Slf4j
class TwoPhaseTermination3{
    // 监控线程
    private Thread monitor;
    //
    private volatile boolean stop = false;

    // 判断该线程是否执行过
    private volatile boolean starting = false;

    // 启动监控线程
    public void start(){
        // 双重检查，可以提高效率
        if (starting){
            synchronized (this){
                // 表示该线程已经在执行了，直接返回即可
                if (starting){
                    return;
                }
                starting = true;    // 第一次执行的时候将状态改为真
            }
        }
        monitor = new Thread(()->{
            while (true){
                Thread currentThread = Thread.currentThread();
                if (stop){
                    log.debug("料理后事");
                    break;
                }
                try {
                    // 睡眠 1 秒
                    TimeUnit.SECONDS.sleep(1);
                    log.debug("执行监控记录");
                } catch (InterruptedException e) {
                }
            }
        });
        monitor.start();
    }

    // 停止监控线程
    public void stop(){
        stop = true;
        monitor.interrupt();
    }
}
